/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.yunyichina.provider.framework.annotation.validate;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Validate the @ValidateSize annotation
 * <p>
 * 深圳医保长度校验规则
 */
public class ValidateSZMedicalSizeHandler implements Handler {

    private static final Logger logger = LoggerFactory.getLogger(ValidateSZMedicalSizeHandler.class);

    public void validate(AnnotationValidable validatedObj, Field field)
            throws ValidateException {
        if (logger.isTraceEnabled()) {
            logger.trace(this.getClass().getName(), "validate()");
        }
        if (field.isAnnotationPresent(ValidateSZMedicalSize.class)) {
            checkSize(validatedObj, field);
        }
    }

    /**
     * validate the String length
     *
     * @param filter interceptor validated object
     * @param field  validated field or property
     * @throws ValidateException
     */
    private void checkSize(AnnotationValidable filter, Field field)
            throws ValidateException {
        if (logger.isTraceEnabled()) {
            logger.trace(this.getClass().getName(), "checkSize()");
        }
        ValidateSZMedicalSize annotation = field.getAnnotation(ValidateSZMedicalSize.class);
        String minSize = annotation.minSize();
        String maxSize = annotation.maxSize();
        String encoding = annotation.encoding();

        int min = 0;
        int max = 0;

        if (!"".equals(minSize)) {
            min = Integer.parseInt(minSize);
        }
        if (!"".equals(maxSize)) {
            max = Integer.parseInt(maxSize);
        }
        
        Object valueObject;
        try {
            valueObject = GetFiledValue.getField(filter, field.getName());
        } catch (Exception ex) {
            logger.error("字段：" + field.getName() + " 获取值发生异常->" + ex.getMessage(), ex);
            throw new ValidateException("字段：" + field.getName() + " 获取值发生异常->" + ex.getMessage(), ex);
        }
        
        if(valueObject==null){
            return;
        }

        String value=String.valueOf(valueObject);
        //重新你计算最大长度，只要包含中文，最大长度减2
        if (!"".equals(maxSize)) {
            try {
                max = getMaxlength(value, max, encoding);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new ValidateException("字段：" + field.getName() + " 转换编码最大长度发生异常1->" + e.getMessage(), e);
            }
        }

        int size = 0;
        if (!"".equals(value) && value != null) {
            try {
                size = value.getBytes(encoding).length;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new ValidateException("字段：" + field.getName() + " 转换编码最大长度发生异常2->" + e.getMessage(), e);
            }
            ;
        }

        if (!"".equals(minSize) && !"".equals(maxSize)) {
            if (size < min || size > max) {
                logger.warn("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",最小长度:" + min + ",byte最大长度:" + max);
                throw new ValidateException("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",最小长度:" + min + ",byte最大长度:" + max);
            }
        }

        if (!"".equals(minSize) && "".equals(maxSize)) {
            if (size < min) {
                logger.warn("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",byte最小长度:" + min);
                throw new ValidateException("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",byte最小长度:" + min);
            }
        }

        if ("".equals(minSize) && !"".equals(maxSize)) {
            if (size > max) {
                logger.warn("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",最大长度:" + max);
                throw new ValidateException("字段：" + field.getName() + "校验失败. 当前值长度:" + size + ",最大长度:" + max);
            }
        }
    }


    private int getMaxlength(String str, int maxLength, String encoding) throws UnsupportedEncodingException {
        int strLength = str.length();
        int strByetsL = str.getBytes(encoding).length;
        if (strByetsL > strLength) {
            return maxLength - 2;
        }
        return maxLength;
    }

}
